/**
 * LibSVMHolderContext.java created by zhangzhidong 
 * at 下午11:20:15 2017年5月3日
 */
package cn.edu.bjtu.entity;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.springframework.util.StringUtils;

import cn.edu.bjtu.classification.libsvm.svm;
import cn.edu.bjtu.classification.libsvm.svm_model;
import cn.edu.bjtu.classification.libsvm.svm_node;
import cn.edu.bjtu.classification.libsvm.driver.svm_train;

/**
 * @author zhangzhidong<br>
 * comment generated at 2017年5月3日下午11:20:15<br>
 * 
 */
public class LibSVMHolderContext {
	svm_model model;
	String in;
	String out;
	
	public String getModelString(){
		return model.toString();
	}
	
	public void train() throws Exception {
		//添加参数
		String argvmodel[]={"-h","0","-t","0",in,out,};
		model = svm_train.main(argvmodel);
	}
	public double classify(svm_node [] x){
		if(x != null){
			return svm.svm_predict(this.model,x);
		}else{
			return -1.0;
		}
	}
	/**
	 * 有类标的情况
	 * 上午12:09:16 2017年5月4日
	 * @param s
	 * @return
	 */
	public double [] distributionLabeled(String s){
		if(s!=null && StringUtils.hasText(s)){
			try{
				//取第一个空格位置
				int anchor = s.indexOf("\t");
				if(anchor == -1){
					anchor = s.indexOf(" ");
				}
				return distribution(s.substring(anchor+1));
			}catch(Exception e){
				e.printStackTrace();
				return null;
			}
		}
		return null;
	}
	
	public double [] distribution(String s){
		if(s!=null && StringUtils.hasText(s)){
			try{
				svm_node [] arr = ff(s);
				return svm.distributionForInstance(this.model, arr);
			}catch(Exception e){
				e.printStackTrace();
				return null;
			}
		}
		return null;
	}
	
	private svm_node[] ff(String s){
		try{
			List<svm_node> list = new ArrayList<svm_node>();
			s = s.trim();
			String nodes[] = s.split(" ");
			for(int i =0;i<nodes.length;i++){
				String[] pieces = nodes[i].split(":");
				int idx = Integer.parseInt(pieces[0]);
				double val = Double.parseDouble(pieces[1]);
				svm_node sn = new svm_node();
				sn.index = idx;
				sn.value = val;
				list.add(sn);
			}
			svm_node [] arr = list.toArray(new svm_node[list.size()]);
			return arr;
		}catch(Exception e){
			e.printStackTrace();
			return null;
		}
			
	}
	
	/**
	 * s 不应该有类标记，例如 s = "1:1.2 2:2.003 3:3.003 4:4.004"
	 * 下午11:34:51 2017年5月3日
	 * @param s
	 * @return
	 */
	public double classify(String s){
		if(s!=null && StringUtils.hasText(s)){
				return classify(ff(s));
		}
		return -1.0;
	}
	/**
	 * 如果 s 有标记呢跳过，忽略标记。
	 *  s = "c1 \t  1:1.2 2:2.003 3:3.003 4:4.004"
	 */
	public double classifyLabeled(String s){
		if(s!=null && StringUtils.hasText(s)){
			try{
				//取第一个空格位置
				int anchor = s.indexOf("\t");
				if(anchor == -1){
					anchor = s.indexOf(" ");
				}
				return classify(s.substring(anchor+1));
			}catch(Exception e){
				e.printStackTrace();
				return -1.0;
			}
		}
		return -1.0;
	}
	/**
	 * 将模型写入到文件里面。sync 来自 unix API
	 * 下午11:29:22 2017年5月3日
	 * @throws IOException
	 */
	public void sync() throws IOException{
		svm.svm_save_model(out,model);
	}
	/**
	 * @return the in
	 */
	public String getIn() {
		return in;
	}

	/**
	 * @param in the in to set
	 */
	public void setIn(String in) {
		this.in = in;
	}

	/**
	 * @return the out
	 */
	public String getOut() {
		return out;
	}

	/**
	 * @param out the out to set
	 */
	public void setOut(String out) {
		this.out = out;
	}

	/**
	 * @return the model
	 */
	public svm_model getModel() {
		return model;
	}

	/**
	 * @param model the model to set
	 */
	public void setModel(svm_model model) {
		this.model = model;
	}
	
	public String toString(){
		if(model==null){
			return " Model hasn't been built";
		}else{
			return model.toString();
		}
	}
	
}
